!	boot.s
!
! 首先利用BIOS中断把内核代码（head代码）加载到内存0x10000处，然后移动到内存0处。
! 最后进入保护模式，并跳转到内存0 （head代码）开始处继续运行。

BOOTSEG = 0x07c0            !引导扇区（本程序）被BIOS加载到内存0x7c00处。
SYSSEG  = 0x1000			!内核（head）先加载到0x10000处，然后移动到0x0处。
SYSLEN  = 17				!内核占用的最大磁盘扇区数。

entry start
start:
	jmpi	go,#BOOTSEG     !段间跳转至0x7c0:go处。当本程序刚运行时所有段寄存器值
go:	mov	ax,cs               !均为0。该跳转语句会把CS寄存器加载为0x7c0  （原为0）。 
	mov	ds,ax               !让DS和SS都指向0x7c0段。 
	mov	ss,ax               
	mov	sp,#0x400		    !设置临时栈指针。其值需大于程序末端并有一定空间即可。

!加载内核代码到内存0x10000开始处。
load_system:
	mov	dx,#0x0000          !利用BIOS中断int 0x13功能2从启动盘读取head代码。
	mov	cx,#0x0002          ! DH -磁头号；DL -驱动器号；CH - 10位磁道号低8位；
	mov	ax,#SYSSEG          ! CL -位7、6是磁道号高2位，位5-0起始扇区号（从1计）。
	mov	es,ax               ! ES:BX -读入缓冲区位置(0x1000:0x0000)。 
	xor	bx,bx               ! AH -读扇区功能号；AL -需读的扇区数（17）。
	mov	ax,#0x200+SYSLEN
	int 	0x13
	jnc	ok_load             !若没有发生错误则跳转继续运行，否则死循环。
die:	jmp	die

! now we want to move to protected mode ...
!把内核代码移动到内存0开始处。共移动8KB字节（内核长度不超过8KB）。
ok_load:
	cli			            !关中断。
	mov	ax, #SYSSEG         !移动开始位置DS:SI = 0x1000:0；目的位置ES:DI=0:0。
	mov	ds, ax
	xor	ax, ax
	mov	es, ax
	mov	cx, #0x1000         !设置共移动4K次，每次移动一个字（word）。 
	sub	si,si
	sub	di,di
	rep movw                !执行重复移动指令。
!加载IDT和GDT基地址寄存器IDTR和GDTR。
	mov	ax, #BOOTSEG        !让DS重新指向0x7c0段。
	mov	ds, ax              !|32位线性基地址|16位表长度|
	lidt	idt_48		! load idt with 0,0 
	lgdt	gdt_48		! load gdt with whatever appropriate

! absolute address 0x00000, in 32-bit protected mode.
	mov	ax,#0x0001	        !lmsw指令在CR0中设置保护模式标志PE （位0）。
	lmsw	ax		        !然后跳转至段选择符值指定的段中，偏移0处。
	jmpi	0,8		        !段选择符值8对应GDT表中第2个段描述符。

!下面是全局描述符表GDT的内容。其中包含3个段描述符。第1个不用，另2个是代码和数据段描述符。 
gdt:	.word	0,0,0,0		! dummy

	.word	0x07FF		! 8Mb - limit=2047 (2048*4096=8Mb)
	.word	0x0000		! base address=0x00000
	.word	0x9A00		! code read/exec
	.word	0x00C0		! granularity=4096, 386

	.word	0x07FF		! 8Mb - limit=2047 (2048*4096=8Mb)
	.word	0x0000		! base address=0x00000
	.word	0x9200		! data read/write
	.word	0x00C0		! granularity=4096, 386

idt_48: .word	0		! idt limit=0
	.word	0,0		! idt base=0L
gdt_48: .word	0x7ff		! gdt limit=2048, 256 GDT entries
	.word	0x7c00+gdt,0	! gdt base = 07xxx
.org 510
	.word   0xAA55      !引导扇区有效标志。必须处于引导扇区最后2字节处。

